home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / C ƒ / TRANS-LSC / MSkelZoom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-04  |  4.4 KB  |  210 lines  |  [TEXT/KAHL]

  1. /*
  2.     TransSkel multiple-window demonstration: ZoomRect module
  3.  
  4.     This module handles a window in which successive randomly generated
  5.     rectangles are smoothly interpolated into one another.  The display
  6.     is white on black, which results in some interesting problems (see
  7.     ZDrawGrowBox, for instance).  The display adjusts itself to the size
  8.     of the window, so that the zoom series always lie entirely within
  9.     the window.  Clicking the mouse in the window pauses the display until
  10.     the button is released.
  11.  
  12.     14 June 1986        Paul DuBois
  13. */
  14.  
  15. # include    "MultiSkel.h"
  16.  
  17.  
  18. # define    zoomSteps    15        /* # rects in interpolative series */
  19.  
  20. WindowPtr            zoomWind;
  21. static Rect            zRect[zoomSteps];    /* set of interpolated rectangles */
  22. static Rect            zSrcRect;
  23. static int            sizeX;                /* size of window in pixels */
  24. static int            sizeY;
  25.  
  26.  
  27. SetZoomSize ()
  28. {
  29. Rect    r;
  30.  
  31.     r = zoomWind->portRect;
  32.     r.right -= 15;                /* don't use right edge */
  33.     sizeX = r.right;
  34.     sizeY = r.bottom;
  35. }
  36.  
  37.  
  38. /*
  39.     return integer between zero and max (inclusive).  assumes max is
  40.     non-negative.
  41. */
  42.  
  43. Rand (max)
  44. int    max;
  45. {
  46. register int    t;
  47.  
  48.     t = Random ();
  49.     if (t < 0) t = -t;
  50.     return (t % (max + 1));
  51. };
  52.  
  53.  
  54. /*
  55.     Interpolate one rectangle smoothly into another.  Erase the previous
  56.     series as the new one is drawn.
  57. */
  58.  
  59. ZoomRect (r1, r2)
  60. Rect    r1, r2;
  61.  
  62. {
  63. register int    r1left, r1top;
  64. register int    l, t;
  65. register int    j;
  66. int                hDiff, vDiff, widDiff, htDiff;
  67. int                r, b;
  68. int                rWid, rHt;
  69.  
  70.  
  71.     r1left = r1.left;
  72.     r1top = r1.top;
  73.     hDiff = r2.left - r1left;    /* positive if moving to right */
  74.     vDiff = r2.top - r1top;        /* positive if moving down */
  75.     rWid = r1.right - r1left;
  76.     rHt = r1.bottom - r1top;
  77.     widDiff = (r2.right - r2.left) - rWid;
  78.     htDiff = (r2.bottom - r2.top) - rHt;
  79. /*
  80.     order of evaluation is important in the rect coordinate calculations.
  81.     since all arithmetic is integer, you can't save time by calculating
  82.     j/zoomSteps and using that - it'll usually be zero.
  83. */
  84.     for (j = 1; j <= zoomSteps; j++)
  85.     {
  86.         FrameRect (&zRect[j-1]);                /* erase a rectangle */
  87.         l = r1left + (hDiff * j) / zoomSteps;
  88.         t = r1top + (vDiff * j) / zoomSteps;
  89.         r = l + rWid + (widDiff * j) / zoomSteps;
  90.         b = t + rHt + (htDiff * j) / zoomSteps;
  91.         SetRect (&zRect[j-1], l, t, r, b);
  92.         FrameRect (&zRect[j-1]);
  93.     }
  94. }
  95.  
  96.  
  97. Idle ()
  98. {
  99. int        i;
  100. Point    pt1, pt2;
  101. Rect    dstRect;
  102.  
  103.     SetPt (&pt1, Rand (sizeX), Rand (sizeY));    /* generate new rect */
  104.     SetPt (&pt2, Rand (sizeX), Rand (sizeY));    /* and zoom to it */
  105.     Pt2Rect (pt1, pt2, &dstRect);
  106.     SetWindClip (zoomWind);            /* don't draw in right edge */
  107.     ZoomRect (zSrcRect, dstRect);
  108.     ResetWindClip ();
  109.     zSrcRect = dstRect;
  110. }
  111.  
  112.  
  113. /*
  114.     just pause zoom display while mouse down
  115. */
  116.  
  117. static Mouse (thePt, t, mods)
  118. Point    thePt;
  119. long    t;
  120. int        mods;
  121.  
  122. {
  123.     while (StillDown ()) {  /* wait until mouse button released */ }
  124. }
  125.  
  126.  
  127. /*
  128.     Draw the grow box in white on black.  This is tricky:  if the window
  129.     is inactive, the grow box will be drawn black, as it should be.  But
  130.     if the window is active, the box will STILL be drawn black on white!
  131.     So have to check whether the window is active or not.  The test for
  132.     active has to be done carefully:  the window manager stores 255 and 0
  133.     for true and false, not real boolean values.
  134. */
  135.  
  136. ZDrawGrowBox ()
  137. {
  138. Rect    r;
  139.  
  140.     PenMode (notPatCopy);
  141.     DrawGrowBox (zoomWind);
  142.     PenMode (patXor);
  143.     if ( ((WindowPeek) zoomWind)->hilited)    /* grow box draw in white */
  144.     {                                        /* no matter what if active */
  145.         r = zoomWind->portRect;                /* - invert to fix */
  146.         r.left = r.right - 14;
  147.         r.top = r.bottom - 14;
  148.         InvertRect (&r);
  149.     }
  150. }
  151.  
  152.  
  153. static Update (resized)
  154. Boolean    resized;
  155. {
  156. int        i;
  157.  
  158.     EraseRect (&zoomWind->portRect);
  159.     ZDrawGrowBox (zoomWind);
  160.     SetWindClip (zoomWind);
  161.     for (i = 0; i < zoomSteps; ++i)
  162.         FrameRect (&zRect[i]);
  163.     ResetWindClip (zoomWind);
  164.     if (resized)
  165.         SetZoomSize ();        /* adjust to new window size */
  166. }
  167.  
  168.  
  169. static Activate (active)
  170. Boolean    active;
  171. {
  172.  
  173.     ZDrawGrowBox (zoomWind);
  174.     if (active)
  175.         DisableItem (editMenu, 0);
  176.     else
  177.         EnableItem (editMenu, 0);
  178.     DrawMenuBar ();
  179. }
  180.  
  181.  
  182. static Halt ()
  183. {
  184.     CloseWindow (zoomWind);
  185. }
  186.  
  187.  
  188. ZoomWindInit ()
  189. {
  190. int        i;
  191.  
  192.     zoomWind = GetNewWindow (zoomWindRes, nil, -1L);
  193.     SkelWindow (zoomWind,
  194.                 Mouse,        /* pause while button down */
  195.                 nil,            /* ignore key clicks */
  196.                 Update,
  197.                 Activate,
  198.                 nil,            /* no close proc */
  199.                 Halt,        /* when done with window */
  200.                 Idle,        /* draw a new series */
  201.                 true);            /* run only when frontmost */
  202.  
  203.     SetZoomSize ();
  204.     BackPat (&black);
  205.     PenMode (patXor);
  206.     SetRect (&zSrcRect, 0, 0, 0, 0);
  207.     for (i = 0; i < zoomSteps; ++i)        /* initialize rect array */
  208.         zRect[i] = zSrcRect;
  209. }
  210.